package satir.record;

import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import satir.analysis.Analytical;
import satir.card.ActionCard;
import satir.card.Choice;
import satir.card.Question;
import satir.framework.LazyInitiator;
import satir.framework.JSONIOPerformer.JSONIOPerformerJSONDecodeException;
import satir.framework.JSONIOPerformer.JSONIOPerformerReadException;

/**
 * The Class Profile.
 * @version 3.0 April 2012
 * @author Creative Family
 */
public class Profile extends SavedEntity {

    /** Player name. */
    private String name;

    /** Game records belongs to the player. */
    private ArrayList<GameRecord> gameRecords;

    /**
     * Instantiates a new profile.
     * @param dBfn
     *            the dB filename
     * @param dBDir
     *            the dB directory
     * @throws JSONIOPerformerReadException
     *             the jSONIO performer read exception
     * @throws JSONIOPerformerJSONDecodeException
     *             the jSONIO performer json decode exception
     * @throws JSONFileInvalidException
     *             the jSON file invalid exception
     */
    public Profile(final String dBfn, final String dBDir)
	    throws JSONIOPerformerReadException,
	    JSONIOPerformerJSONDecodeException, JSONFileInvalidException {
	super(dBfn, dBDir);
    }

    /**
     * Instantiates a new profile.
     * @param name
     *            the name
     * @throws JSONIOPerformerReadException
     *             the jSONIO performer read exception
     * @throws JSONIOPerformerJSONDecodeException
     *             the jSONIO performer json decode exception
     * @throws JSONFileInvalidException
     *             the jSON file invalid exception
     */
    public Profile(final String name) throws JSONIOPerformerReadException,
	    JSONIOPerformerJSONDecodeException, JSONFileInvalidException {
	this(name + "/Profile.json", "temp/");
	setName(name);
    }

    /**
     * Gets the name.
     * @return the name
     */
    public String getName() {
	return name;
    }

    /**
     * Gets appellation.
     * @return appellation
     */
    @Override
    protected String getAppellation() {
	return "Profile";
    }

    /**
     * Initialize record object list.
     */
    @Override
    protected void initializeEssentialObjects() {
	gameRecords = new ArrayList<GameRecord>();
	name = "";
    }

    /**
     * Sets the name.
     * @param name
     *            the new name
     */
    public void setName(final String name) {

	JSONObject profileJson = getJSONObject();
	try {
	    this.name = name;
	    profileJson.put("name", name);

	} catch (JSONException e) {
	    e.printStackTrace();
	}
    }

    /**
     * Adds the game records.
     * @param gameRecord
     *            the game record
     */
    public void addGameRecords(final GameRecord gameRecord) {
	gameRecords.add(gameRecord);
	JSONObject profileJson = getJSONObject();
	try {
	    if (!(profileJson.has("gameRecord"))) {
		profileJson.put("gameRecord", new JSONArray());
	    }
	    profileJson.getJSONArray("gameRecord").put(
		    gameRecord.getDBFilename());
	} catch (JSONException e) {
	    e.printStackTrace();
	}
    }

    /**
     * Gets the analyticals.
     * @return the analyticals
     */
    public ArrayList<Analytical> getAnalyticals() {
	ArrayList<Analytical> analyticals = new ArrayList<Analytical>();

	for (int i = 0; i < gameRecords.size(); i++) {
	    GameRecord record = gameRecords.get(i);
	    ArrayList<Recordable> recordables = record.getRecords(this);

	    for (int j = 0; j < recordables.size(); j++) {
		Recordable recordable = recordables.get(j);

		// Specific for Action Card, to-be refectoring in the further
		ActionCard card = (ActionCard) LazyInitiator.get(
			recordable.getClassType(), recordable.getKey());
		try {
		    Analytical analytical = null;
		    boolean found = false;
		    JSONArray answers = new JSONArray(recordable.getAction());
		    for (int k = 0; k < answers.length(); k++) {
			String answer = answers.getString(k);
			ArrayList<Question> questions = card.getQuestions();
			for (int l = 0; l < questions.size(); l++) {
			    Question question = questions.get(l);
			    ArrayList<Choice> choices = question.getChoices();
			    for (int m = 0; m < choices.size(); m++) {
				Choice choice = choices.get(m);
				if (choice.getContent().equals(answer)) {
				    found = true;
				    analytical = choice;
				}
			    }
			    if (found) {
				break;
			    }
			}
			if (found) {
			    analyticals.add(analytical);
			}
		    }

		} catch (JSONException e) {
		    e.printStackTrace();
		}
	    }
	}
	return analyticals;
    }

    /**
     * Initialize the profile from specific JSON data.
     * @param json
     *            the JSON
     * @throws JSONException
     *             the jSON exception
     * @throws JSONIOPerformerReadException
     *             the jSONIO performer read exception
     * @throws JSONIOPerformerJSONDecodeException
     *             the jSONIO performer JSON decode exception
     */
    @Override
    protected void initializeFromJSON(final JSONObject json) throws JSONException,
	    JSONIOPerformerReadException, JSONIOPerformerJSONDecodeException {

	JSONObject profile = json;

	// Start initialization
	name = profile.getString("name");

	JSONArray tmpGameRecords = profile.getJSONArray("gameRecord");

	for (int i = 0; i < tmpGameRecords.length(); i++) {
	    String tmpGameKey = tmpGameRecords.getString(i);

	    gameRecords.add(new GameRecord(tmpGameKey, getDBDirectory()));
	}
    }

    /**
     * Create new record to JSON.
     */
    @Override
    protected void createNewToJSON() {
	try {
	    getJSONObject().put("name", name);
	    getJSONObject().put("gameRecord", new JSONArray());
	} catch (JSONException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }
}
